// LocalPlayerController.ts
import {  _decorator, Component, EventKeyboard, Input, input, KeyCode, SystemEvent, v2, Vec2 } from 'cc';
import { InputCommand, PlayerState } from './types';
import { NetworkManager } from './NetManager';
import { MsgTypes } from './MsgTypes';
import { Msg_Input_Req } from './msgs';

const {ccclass, property} = _decorator;

@ccclass
export default class LocalPlayerController extends Component {
    @property
    public moveSpeed: number = 300;
    
    @property
    public predictionSmoothing: number = 0.1;
    
    // 输入状态
    private currentInput: Vec2 = v2(0, 0);
    private lastSentInput: Vec2 = v2(0, 0);
    private inputChanged: boolean = false;
    private inputSequence: number = 0;
    private lastInputSequence: number = 0;
    private pendingInputs: InputCommand[] = [];
    private sendTimer: number = 0;
    private sendInterval: number = 50;//50ms发送一次输入信息

    
    // 状态
    private currentState: PlayerState = new PlayerState();
    private serverVerifiedState: PlayerState = new PlayerState();
    
    onLoad() {
        this.setupInput();
    }
    initState(state: PlayerState) {
        // 初始化为当前状态
        this.currentState = state.clone();
        this.serverVerifiedState = state.clone(); 
    }
    
    update(dt: number) {
        this.processLocalMovement(dt);
        this.sendInputToServer(dt);
    }
    
    private setupInput() {
        input.on(Input.EventType.KEY_DOWN, this.onKeyDown, this);
        input.on(Input.EventType.KEY_UP, this.onKeyUp, this);
        
        // 移动端触摸输入
        // this.node.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
        // this.node.on(Node.EventType.TOUCH_END, this.onTouchEnd, this);
    }
    
    private onKeyDown(event:EventKeyboard) {
        let newInput = this.currentInput.clone()
        switch(event.keyCode) {
            case KeyCode.KEY_W:
                newInput.y = 1;
                break;
            case KeyCode.KEY_S:
                newInput.y = -1;
                break;
            case KeyCode.KEY_A:
                newInput.x = -1;
                break;
            case KeyCode.KEY_D:
                newInput.x = 1;
                break;
        }
        this.updateInputDirection(newInput);
    }
    
    private onKeyUp(event: EventKeyboard) {
        let newInput = this.currentInput.clone()
        switch(event.keyCode) {
            case KeyCode.KEY_W:
            case KeyCode.KEY_S:
                newInput.y = 0;
                break;
            case KeyCode.KEY_A:
            case KeyCode.KEY_D:
                newInput.x = 0;
                break;
        }
        this.updateInputDirection(newInput);
    }
    
        // 只有在输入真正变化时才更新
    private updateInputDirection(newInput:Vec2) {
        // 检查输入是否真正发生变化
        if (!this.isInputChanged(this.currentInput, newInput)) {
            return;
        }
        
        this.currentInput = newInput;
        this.inputChanged = true;
        
        // 立即创建输入命令
        this.createInputCommand();
    }
        // 创建输入命令
    private createInputCommand() {
        const inputCmd = new InputCommand(
            this.inputSequence++,
            this.currentInput.clone(),
            this.currentState.position.clone(),
            Date.now()
        );
        
        this.pendingInputs.push( inputCmd);
        this.lastSentInput = this.currentInput.clone();
    }
    private isInputChanged(oldInput: Vec2, newInput: Vec2): boolean {
        const deadZone = 0.1; // 输入死区
        
        // 检查是否从无输入变为有输入，或从有输入变为无输入,这里主要是为了防止细微的抖动导致频繁发送输入命令。
        //触摸下的检测
        const oldMagnitude = oldInput.length();
        const newMagnitude = newInput.length();
        
        if ((oldMagnitude < deadZone) !== (newMagnitude < deadZone)) {
            return true;
        }
        
        // 检查方向变化（超过45度角变化）
        if (oldMagnitude >= deadZone && newMagnitude >= deadZone) {
            const dot = oldInput.normalize().dot(newInput.normalize());
            if (dot < 0.7) { // 大约45度
                return true;
            }
        }
        
        return false;
    }
    // private onTouchMove(event: Event.EventTouch) {
    //     const touchPos = event.getLocation();
    //     const nodePos = this.node.parent.convertToNodeSpaceAR(touchPos);
    //     const direction = nodePos.sub(this.node.position).normalize();
        
    //     this.inputDirection.x = direction.x;
    //     this.inputDirection.y = direction.y;
    // }
    
    // private onTouchEnd() {
    //     this.inputDirection = v2(0, 0);
    // }
    
    // 本地移动处理（客户端预测）
    private processLocalMovement(dt: number) {
        if (!this.currentInput.equals(v2(0, 0))) {
            const normalizedInput = this.currentInput.normalize();
            const velocity = normalizedInput.multiplyScalar(this.moveSpeed);
            
            // 更新预测状态
            this.currentState.position = this.currentState.position.add(velocity.multiplyScalar(dt));
            this.currentState.velocity = velocity;
            //TODO 时间用服务器的时间？
            this.currentState.timestamp = Date.now();
            
            // 立即更新显示位置
            this.node.setPosition(this.currentState.position.x,this.currentState.position.y);
            
        } else {
            this.currentState.velocity = v2(0, 0);
        }
    }
    
    // 发送输入到服务器
    private sendInputToServer(dt:number) {
        this.sendTimer+=dt
        if ((this.sendTimer>=this.sendInterval || this.inputChanged)  && this.pendingInputs.length > 0) {
            NetworkManager.getInstance().sendMessage(MsgTypes.Move,new Msg_Input_Req(this.pendingInputs))
            this.sendTimer=0
            this.inputChanged=false
        }
    }
    
    // 接收服务器状态确认
    public onServerStateConfirm(serverState: PlayerState, lastProcessedSequence: number) {
        // 更新服务器验证状态
        this.serverVerifiedState = serverState.clone();
        
        // 移除已处理的输入
        this.pendingInputs = this.pendingInputs.filter(
            input => input.sequence > lastProcessedSequence
        );
        
        // 如果预测误差过大，进行纠正
        this.reconcileWithServer(serverState);
    }
    
    // 与服务器状态调和
    private reconcileWithServer(serverState: PlayerState) {
        const errorDistance = this.currentState.position.divide(serverState.position).length();
        
        if (errorDistance > 10) { // 误差阈值
            console.log(`预测误差过大: ${errorDistance}, 进行纠正`);
             // 从服务器验证状态重新开始预测
            this.currentState.position = serverState.position.clone();
            this.currentState.velocity = serverState.velocity.clone();
            // 重新应用所有未确认的输入
            this.reapplyPendingInputs();
            // 立即更新显示
            this.node.setPosition(this.currentState.position.x,this.currentState.position.y);
        }
    }
        // 重新应用未确认的输入
    private reapplyPendingInputs() {
        const sortedInputs = Array.from(this.pendingInputs.values())
            .sort((a, b) => a.sequence - b.sequence);
        
        let currentState = this.serverVerifiedState.clone();
        
        for (let input of sortedInputs) {
            const timeDiff = (input.timestamp - currentState.timestamp) / 1000;
            if (timeDiff > 0) {
                const velocity = input.direction.normalize().multiplyScalar(this.moveSpeed);
                currentState.position = currentState.position.add(velocity.multiplyScalar(timeDiff));
                currentState.velocity = velocity;
                currentState.timestamp = input.timestamp;
            }
        }
        
        this.currentState = currentState;
    }

}